import time
from typing import Dict, Any, Optional
import httpx
from tenacity import retry, stop_after_attempt, wait_exponential
from intelli_port.commons.audit import audit_event, write_ops_log
from intelli_port.commons.config import load_settings

@retry(reraise=False, stop=stop_after_attempt(3), wait=wait_exponential(multiplier=0.2, min=0.2, max=2.0))
def pay_authorize(payload: Dict[str, Any], idem_key: Optional[str] = None) -> Dict[str, Any]:
    s = load_settings()
    if getattr(s, "payments_base_url", ""):
        try:
            headers = {"Authorization": f"Bearer {s.external_auth_token}"} if getattr(s, "external_auth_token", "") else {}
            if idem_key:
                headers["X-Idempotency-Key"] = str(idem_key)
            with httpx.Client(timeout=float(getattr(s, "external_timeout_s", 2.0))) as client:
                r = client.post(s.payments_base_url.rstrip("/") + "/authorize", json=payload, headers=headers)
                if r.status_code == 200:
                    return r.json()
        except Exception:
            pass
    audit_event(
        "authorize",
        "payment",
        "pay",
        payload,
        user_id=payload.get("user_id"),
        amount=payload.get("amount"),
        currency=payload.get("currency"),
        device_id=payload.get("device_id"),
        risk_flags=payload.get("risk_flags"),
        decision="authorize",
        tool_name="payments",
    )
    return {"auth_id": str(int(time.time() * 1000)), "status": "authorized"}

@retry(reraise=False, stop=stop_after_attempt(3), wait=wait_exponential(multiplier=0.2, min=0.2, max=2.0))
def pay_capture(auth_id: str, payload: Dict[str, Any], idem_key: Optional[str] = None) -> Dict[str, Any]:
    s = load_settings()
    if getattr(s, "payments_base_url", ""):
        try:
            headers = {"Authorization": f"Bearer {s.external_auth_token}"} if getattr(s, "external_auth_token", "") else {}
            if idem_key:
                headers["X-Idempotency-Key"] = str(idem_key)
            with httpx.Client(timeout=float(getattr(s, "external_timeout_s", 2.0))) as client:
                r = client.post(s.payments_base_url.rstrip("/") + "/capture", json={"auth_id": auth_id, **payload}, headers=headers)
                if r.status_code == 200:
                    return r.json()
        except Exception:
            pass
    txn_id = str(int(time.time() * 1000))
    write_ops_log("INFO", "payment.capture", {"auth_id": auth_id, "txn_id": txn_id, "payload": payload})
    audit_event(
        "capture",
        "payment",
        "pay",
        payload,
        user_id=payload.get("user_id"),
        amount=payload.get("amount"),
        currency=payload.get("currency"),
        device_id=payload.get("device_id"),
        risk_flags=payload.get("risk_flags"),
        decision="capture",
        result="success",
        txn_id=txn_id,
        tool_name="payments",
    )
    return {"txn_id": txn_id, "status": "captured"}

@retry(reraise=False, stop=stop_after_attempt(3), wait=wait_exponential(multiplier=0.2, min=0.2, max=2.0))
def pay_refund(txn_id: str, payload: Dict[str, Any], idem_key: Optional[str] = None) -> Dict[str, Any]:
    s = load_settings()
    if getattr(s, "payments_base_url", ""):
        try:
            headers = {"Authorization": f"Bearer {s.external_auth_token}"} if getattr(s, "external_auth_token", "") else {}
            if idem_key:
                headers["X-Idempotency-Key"] = str(idem_key)
            with httpx.Client(timeout=float(getattr(s, "external_timeout_s", 2.0))) as client:
                r = client.post(s.payments_base_url.rstrip("/") + "/refund", json={"txn_id": txn_id, **payload}, headers=headers)
                if r.status_code == 200:
                    return r.json()
        except Exception:
            pass
    refund_id = str(int(time.time() * 1000))
    write_ops_log("INFO", "payment.refund", {"txn_id": txn_id, "refund_id": refund_id, "payload": payload})
    audit_event(
        "refund",
        "payment",
        "refund",
        payload,
        user_id=payload.get("user_id"),
        amount=payload.get("amount"),
        currency=payload.get("currency"),
        device_id=payload.get("device_id"),
        risk_flags=payload.get("risk_flags"),
        decision="refund",
        result="success",
        txn_id=txn_id,
        tool_name="payments",
    )
    return {"refund_id": refund_id, "status": "succeeded"}